import { useState } from 'react';
import styles from './index.less';
import { InputNumber, Button } from 'antd';
import BarChart from '@/components/charts/barChart/index';
import { generateRandomArray } from '@/utils/arrayGenerator';
import {
    bubbleSort,
    heapSort,
    selectionSort,
    insertionSort,
    shellSort,
    mergeSort,
    quickSort,
    bucketSort,
    countingSort,
    radixSort,
    gnomeSort,
    cocktailSort,
    timsort,
} from './functions/index';

const sortList = [
    { type: 'bubbleSort', name: '冒泡排序' },
    { type: 'heapSort', name: '堆排序' },
    { type: 'selectionSort', name: '选择排序' },
    { type: 'insertionSort', name: '插入排序' },
    { type: 'shellSort', name: '希尔排序' },
    { type: 'mergeSort', name: '归并排序' },
    { type: 'quickSort', name: '快速排序' },
    { type: 'bucketSort', name: '桶排序' },
    { type: 'countingSort', name: '计数排序' },
    { type: 'radixSort', name: '基数排序' },
    { type: 'gnomeSort', name: '地精排序' },
    { type: 'cocktailSort', name: '鸡尾酒排序' },
    { type: 'timsort', name: 'Tim排序' },
];

export default () => {
    const [dataLength, setDataLength] = useState<number>(2000);
    const [sortArray, setSortArray] = useState<number[]>([]);
    const [time, setTime] = useState<number>(0);

    const generateNewArray = () => {
        const newArray = generateRandomArray(dataLength, 0, dataLength * 2);
        setSortArray(newArray);
    }

    const sortByType = (type: string) => {
        const t1 = performance.now();
        let sortResult: number[] = [];
        switch (type) {
            case 'bubbleSort':
                sortResult = bubbleSort(sortArray);
                break;
            case 'heapSort':
                sortResult = heapSort(sortArray);
                break;
            case 'selectionSort':
                sortResult = selectionSort(sortArray);
                break;
            case 'insertionSort':
                sortResult = insertionSort(sortArray);
                break;
            case 'shellSort':
                sortResult = shellSort(sortArray);
                break;
            case 'mergeSort':
                sortResult = mergeSort(sortArray);
                break;
            case 'quickSort':
                sortResult = quickSort(sortArray, 0, sortArray.length - 1);
                break;
            case 'bucketSort':
                sortResult = bucketSort(sortArray, 10);
                break;
            case 'countingSort':
                sortResult = countingSort(sortArray, dataLength * 2);
                break;
            case 'radixSort':
                sortResult = radixSort(sortArray, (dataLength + '').length);
                break;
            case 'gnomeSort':
                sortResult = gnomeSort(sortArray);
                break;
            case 'cocktailSort':
                sortResult = cocktailSort(sortArray);
                break;
            case 'timsort':
                sortResult = timsort(sortArray, 32);
                break;
            default:
                sortResult = quickSort(sortArray, 0, sortArray.length - 1);
        }
        const t2 = performance.now();
        setTime(t2 - t1);
        setSortArray(sortResult);
    }

    const generateSequence = (n: number): string[] => {
        const sequence: string[] = [];
        for (let i = 1; i <= n; i++) {
            sequence.push('' + i);
        }
        return sequence;
    }

    return (
        <div className={styles.container}>
            <p className={styles.title}>排 序 算 法</p>
            <div className={styles.row}>
                <InputNumber
                    addonBefore="数组长度" 
                    defaultValue={5000}
                    value={dataLength}
                    onChange={(value: number | null) => {
                        setDataLength(value || 0);
                    }}
                />
                <Button className={styles.generateButton} onClick={generateNewArray}>生成随机数组</Button>
                <span className={styles.time}>耗时：{time > 0 ? time.toFixed(4) : '00'}毫秒</span>
            </div>
            <div className={styles.row}>
                {sortList.map(i => {
                    return (
                        <Button className={styles.sortButton} key={i.type} onClick={() => sortByType(i.type)}>{i.name}</Button>
                    );
                })}
            </div>
            <div className={styles.chartLayout}>
                <BarChart
                    id='sortChart'
                    grid={{
                        left: 12,
                        right: 12,
                        top: 12,
                        bottom: 12,
                        containLabel: true,
                    }}
                    xData={generateSequence(dataLength)}
                    yData={sortArray}
                    barWidth={1}
                    barMaxWidth={1}
                />
            </div>
        </div>
    );
}